package com.project.frba.bi.descriptor;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;



public class Join {
	
	private DatabaseDescriptor descriptor;
	private String name;
	private String table;
	private List<JoinCondition> joinConditions = new ArrayList<JoinCondition>();
	
	public Join(String name, DatabaseDescriptor descriptor) {
		this.name = name;
		this.descriptor = descriptor;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getTable() {
		return table;
	}
	public void setTable(String table) {
		this.table = table;
	}
	
	public Node getMyNode() throws XPathExpressionException{
		return this.descriptor.getNode("/bi/facttable/joins/join[@name = '" + this.getName() + "']");
	}
	
	public String getJoin(){
		StringBuffer joinBuffer = new StringBuffer("INNER JOIN " + this.table + " AS " + this.name + " ON " );
		for (JoinCondition joinCondition : joinConditions) {
			joinBuffer.append(this.name + "." + joinCondition.getColumn() + " = " + joinCondition.getFactColumn() + " AND ");
		}
		joinBuffer.append("1=1");
		return joinBuffer.toString();
	}

	public DatabaseDescriptor getDescriptor() {
		return descriptor;
	}

	public void setDescriptor(DatabaseDescriptor descriptor) {
		this.descriptor = descriptor;
	}

	public void loadJoin() throws XPathExpressionException {
		Node joinNode = this.getMyNode();
		NamedNodeMap attributes = joinNode.getAttributes();
		this.setTable(attributes.getNamedItem("table").getNodeValue());
		
		NodeList joinConditionNodes = joinNode.getChildNodes();
		for (int i = 0; i < joinConditionNodes.getLength(); i++) {
			Node joinConditionNode = joinConditionNodes.item(i);
			if (joinConditionNode.getNodeName().endsWith("condition")) {
				JoinCondition joinCondition = new JoinCondition(joinConditionNode);
				joinConditions.add(joinCondition);
			}
		}
		this.descriptor.addJoin(this);
	}
	
	public void removeJoinCondition(JoinCondition joinCondition){
		this.joinConditions.remove(joinCondition);
	}
	
	public ArrayList<JoinCondition> getJoinConditions(){
		return (ArrayList<JoinCondition>) this.joinConditions;
	}
	
	public void addJoinCondition(JoinCondition joinCondition){
		this.joinConditions.add(joinCondition);
	}
}
